package com.maysev.myjob_backend.interceptor;

import com.alibaba.fastjson.JSON;
import com.maysev.myjob_backend.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 五七
 * @create 2023-04-09 13:41
 * @description:
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    //路径匹配器，支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    /**
     * 访问接口前执行,在这里验证登录状态的业务逻辑,可以在用户调用指定接口之前验证登陆状态了
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {




        String[] uris = new String[]{
                "/student/login",
                "/student/regist",
                "/recruiter/login",
                "recruiter/regist",
                "/common/download/**"
        };
        //获取当前路径
        String uri = request.getRequestURI();


        //2、判断本次请求是否需要处理
        boolean check = check(uris, uri);

        //3、如果不需要处理，则直接放行
        if(check){
            log.info("不需要处理的URI：{}",uri);
//            filterChain.doFilter(request,response);
            return true;
        }

        String token ="";
        // 如果是 OPTIONS 请求，我们就让他通过，不管他
        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
            // 如果不是，我们就把token拿到，用来做判断
        }else {
            token = request.getHeader("token");
        }
        //2.拿到请求头里面的token（如果是第一次登录，那么是没有请求头的）
//        String token = request.getHeader("Token");
        if(token==null){
            response.setContentType("application/json; charset=utf-8");

            //2.1 拦截请求并返回信息给前台 （前台后置拦截器就是根据这里面返回的json数据，来判读并跳转到登录界面）
            R<Object> error = R.error("NO LOGIN");
            String s = JSON.toJSONString(error);
            response.getWriter().print(s );
//            response.getWriter().print("{\"success\":false,\"msg\":\"NoLogin\"}");

            return false;
        }

        //3、如果有token，那么就根据这个token从redis查询登录用户信息，如果redis里面还没过期，那么就正常放行，没有就进行拦截，并返回信息，叫他重新登录
        String tokenVal = (String) redisTemplate.opsForValue().get("token");
//        String tokenUser = RedisUtils.INSTANCE.get(token);
        if(tokenVal==null){
            response.setContentType("application/json; charset=utf-8");

            R<Object> error = R.error("NO LOGIN");
            String s = JSON.toJSONString(error);
            response.getWriter().print(s );
            return false;
        }

        //4.如果没有过期，那么就重新将token和登录用户信息存到redis
        redisTemplate.opsForValue().set("token",tokenVal,60, TimeUnit.MINUTES);
//        RedisUtils.INSTANCE.set(token, tokenUser, 60*30);

        return true;


    }

    public boolean check(String[] urls,String requestURI){
        for (String url : urls){
            boolean match = PATH_MATCHER.match(url,requestURI);
            if(match){
                return true;
            }
        }
        return false;
    }
}
